# src/utils/discord_permission_checker.py
import logging
import asyncio
import aiohttp
from aiohttp_socks import ProxyType, ProxyConnector
from urllib.parse import urlencode


# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


async def get_channel_info(session, channel_id):
    """
    获取频道信息（包括所属服务器 ID）
    """
    url = f"https://discord.com/api/v9/channels/{channel_id}"
    try:
        async with session.get(url) as resp:
            if resp.status == 200:
                return await resp.json()
            else:
                logger.error(f"❌ 获取频道信息失败，状态码: {resp.status}")
                logger.debug(f"响应内容: {await resp.text()}")
                return None
    except Exception as e:
        logger.error(f"⚠️ 请求失败: {str(e)}", exc_info=True)
        return None


async def check_guild_membership(session, guild_id):
    """
    检查 Bot 是否已加入指定服务器
    """
    url = f"https://discord.com/api/v9/guilds/{guild_id}/members/@me"
    try:
        async with session.get(url) as resp:
            if resp.status == 200:
                data = await resp.json()
                logger.info("✅ Bot 成功加入服务器")
                logger.info(f"🧑‍🤝‍🧑 角色: {data.get('roles', [])}")
                return True
            elif resp.status == 404:
                logger.error("❌ Bot 未加入该服务器")
                return False
            elif resp.status == 403:
                logger.error("❌ Bot 被禁止访问该服务器")
                return False
            else:
                logger.warning(f"⚠️ 未知状态码: {resp.status}")
                logger.debug(f"响应内容: {await resp.text()}")
                return False
    except Exception as e:
        logger.error(f"⚠️ 请求失败: {str(e)}", exc_info=True)
        return False


def generate_oauth2_link(client_id):
    """
    生成加入 Discord 官方 API 测试服务器的授权链接
    """
    base_url = "https://discord.com/oauth2/authorize"
    params = {
        "client_id": client_id,
        "scope": "bot",
        "permissions": "277025313840"
    }
    return f"{base_url}?{urlencode(params)}"


async def check_discord_permissions(bot_token, channel_id, proxy_url="http://127.0.0.1:7890"):
    """
    主函数：检查 Bot 是否有权访问频道，并给出修复建议
    """
    connector = ProxyConnector(
        proxy_type=ProxyType.HTTP,
        host="127.0.0.1",
        port=7890,
        ssl=False
    )

    headers = {
        "Authorization": f"Bot {bot_token}",
        "User-Agent": "DiscordBot (https://github.com/yourname/yourproject, 1.0)",
        "Content-Type": "application/json"
    }

    async with aiohttp.ClientSession(headers=headers, connector=connector) as session:
        logger.info("🔍 正在获取频道信息...")

        channel_data = await get_channel_info(session, channel_id)

        if not channel_data:
            logger.error("🚫 无法获取频道信息，请确认频道 ID 是否有效")
            return

        guild_id = channel_data.get("guild_id")
        logger.info(f"🌐 频道所属服务器 ID: {guild_id}")

        logger.info("🧾 正在检查 Bot 是否加入了服务器...")
        is_member = await check_guild_membership(session, guild_id)

        if not is_member:
            logger.warning("🚫 Bot 未加入服务器，请使用以下链接授权加入官方测试服务器：")
            logger.warning(generate_oauth2_link("你的 Bot Client ID"))
            return

        logger.info("📨 正在尝试获取频道消息...")

        messages_url = f"https://discord.com/api/v9/channels/{channel_id}/messages?limit=50"

        try:
            async with session.get(messages_url) as resp:
                if resp.status == 200:
                    logger.info("✅ Bot 可以正常访问该频道！")
                elif resp.status == 403:
                    logger.error("❌ Bot 没有访问该频道的权限")
                    logger.debug(f"响应内容: {await resp.text()}")
                    logger.warning("🪛 请检查 Bot 所属角色的权限:")
                    logger.warning("- View Channel")
                    logger.warning("- Read Message History")
                else:
                    logger.error(f"❌ 获取消息失败，状态码: {resp.status}")
                    logger.debug(f"响应内容: {await resp.text()}")
        except Exception as e:
            logger.error(f"⚠️ 请求失败: {str(e)}", exc_info=True)


if __name__ == "__main__":
    BOT_TOKEN = "MTM4NzI3OTgwMzAxNDQ1MTI4MA.GGB0yz._ZmfJ1M60b4tAXdlTMzQh-MqK7glHFG3ZCWRD4"
    CHANNEL_ID = "1130737745757753485"  # Discord 官方测试频道 #general

    asyncio.run(check_discord_permissions(BOT_TOKEN, CHANNEL_ID))